﻿// ....................................................................................................................
//	Author: Copyright (C) 2012 Ing. Marek Hubal
//	Email: hubal@acasoftware.org
// ....................................................................................................................

using System;

namespace core
{
    /// <summary>Trieda ICore</summary>
    public class ICore
    {
        public const int TS_FALSE = 0;
        public const int TS_TRUE = 1;
        public const int TS_NONE = 2;

        public const int CLIPBOARD_TYPE_TEXT = 1;
        public const int CLIPBOARD_TYPE_BITMAP = 2;

        public const int FILE_TYPE_TXT = 1;
        public const int FILE_TYPE_BMP = 2;
        public const int FILE_TYPE_JPG = 3;
        public const int FILE_TYPE_PNG = 4;
        public const int FILE_TYPE_UNICODE_TXT = 5;

        protected static readonly string[] DoubleConvertTable = { "#", "#.0", "#.00", "#.000", "#.0000", "#.00000", "#.000000", "#.0000000", "#.00000000", "#.000000000", "#.0000000000", "#.00000000000", "#.000000000000" };
        protected const string ThousandSeparator = " ";

        /// <summary>Bezpecne dispose objektu</summary>
        /// <param name="pValue">objekt pre dispose</param>
        /// <returns>null</returns>
        public static object DisposeObject(IDisposable pValue)
        {
            if (pValue != null) pValue.Dispose(); // Volam dispose
            pValue = null;
            return null;
        }

        /// <summary>Prevod objektu na string</summary>
        /// <param name="pValue">objekt pre prevod</param>
        /// <returns>prevedena hodnota</returns>
        public static string ToStr(object pValue)
        {
            try
            {
                if (pValue == null) return ""; // Prazdny vstup?
                return Convert.ToString(pValue); // Volam prevod a vratim vysledok
            }
            catch
            {
                return ""; // Chyba
            }
        }
        /// <summary>Prevod objektu na int</summary>
        /// <param name="pValue">objekt pre prevod</param>
        /// <returns>prevedena hodnota</returns>
        public static int ToInt(object pValue)
        {
            try
            {
                if (pValue == null) return 0; // Prazdny vstup?
                return Convert.ToInt32(pValue); // Volam prevod a vratim vysledok
            }
            catch
            {
                return 0; // Chyba
            }
        }
        /// <summary>Prevod objektu na uint</summary>
        /// <param name="pValue">objekt pre prevod</param>
        /// <returns>prevedena hodnota</returns>
        public static uint ToUInt(object pValue)
        {
            try
            {
                if (pValue == null) return 0; // Prazdny vstup?
                return Convert.ToUInt32(pValue); // Volam prevod a vratim vysledok
            }
            catch
            {
                return 0; // Chyba
            }
        }
        /// <summary>Prevod objektu na long</summary>
        /// <param name="pValue">objekt pre prevod</param>
        /// <returns>prevedena hodnota</returns>
        public static long ToLong(object pValue)
        {
            try
            {
                if (pValue == null) return 0; // Prazdny vstup?
                return Convert.ToInt64(pValue); // Volam prevod a vratim vysledok
            }
            catch
            {
                return 0; // Chyba
            }
        }
        /// <summary>Prevod objektu na ulong</summary>
        /// <param name="pValue">objekt pre prevod</param>
        /// <returns>prevedena hodnota</returns>
        public static ulong ToULong(object pValue)
        {
            try
            {
                if (pValue == null) return 0; // Prazdny vstup?
                return Convert.ToUInt64(pValue); // Volam prevod a vratim vysledok
            }
            catch
            {
                return 0; // Chyba
            }
        }
        /// <summary>Prevod double na string</summary>
        /// <param name="pValue">hodnota pre prevod</param>
        /// <param name="pDecimals">pocet desatinnych miest - max. 12</param>
        /// <returns>prevedena hodnota</returns>
        public static string Dbl2Str(double pValue, int pDecimals = 12)
        {
            try
            {
                if ((pDecimals < 0) || (pDecimals > 12)) pDecimals = 12;
                return pValue.ToString(DoubleConvertTable[pDecimals]).Replace(',', '.');
            }
            catch
            {
                return ""; // Chyba
            }
        }
        /// <summary>Prevod retazca na double</summary>
        /// <param name="pValue">hodnota na prevod</param>
        /// <returns>prevedena hodnota</returns>
        public static double Str2Dbl(string pValue)
        {
            try
            {
                double D;
                if (string.IsNullOrEmpty(pValue)) return 0.0; // Prazdny vstup?
                return double.TryParse(pValue.Replace(',', '.'), System.Globalization.NumberStyles.AllowDecimalPoint | System.Globalization.NumberStyles.AllowLeadingSign, System.Globalization.CultureInfo.InvariantCulture, out D) ? D : 0.0; // Pevediem
            }
            catch
            {
                return 0.0; // Chyba
            }
        }
        /// <summary>Prevod bool na string</summary>
        /// <param name="pValue">hodnota na prevod</param>
        /// <returns>prevedena hodnota</returns>
        public static string Bool2Str(bool pValue)
        {
            return pValue ? lang.APPFORM_TEXT_4_1 : lang.APPFORM_TEXT_4_2;
        }
        /// <summary>Prevod datumu na retazec</summary>
        /// <param name="pValue">hodnota</param>
        /// <returns>retazec</returns>
        public static string DateTime2Str(DateTime pValue)
        {
            return pValue.ToString("dd.MM.yyyy HH:mm:ss");
        }
        /// <summary>Prevod Unix casu na DateTime</summary>
        /// <param name="unixTime">unixovsky cas</param>
        /// <returns>datetime objekt</returns>
        public static DateTime UnixTime2DateTime(uint unixTime)
        {
            DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return origin.AddSeconds((double)unixTime).ToLocalTime();
        }
        /// <summary>Prevod unixovskeho modu na retazec</summary>
        /// <param name="pValue">hodnota</param>
        /// <returns>vysledok</returns>
        public static string UnixModeToString(uint pValue)
        {
            char CH0, CH1, CH2, CH3, CH4, CH5, CH6, CH7, CH8;

            CH0 = (pValue & 0x100) == 0 ? '-' : 'r';
            CH1 = (pValue & 0x80) == 0 ? '-' : 'w';
            if ((pValue & 0x800) == 0) CH2 = (pValue & 0x40) == 0 ? '-' : 'x';
            else CH2 = (pValue & 0x40) == 0 ? 'S' : 's';
            CH3 = (pValue & 0x20) == 0 ? '-' : 'r';
            CH4 = (pValue & 0x10) == 0 ? '-' : 'w';
            if ((pValue & 0x400) == 0) CH5 = (pValue & 0x8) == 0 ? '-' : 'x';
            else CH5 = (pValue & 0x8) == 0 ? 'S' : 's';
            CH6 = (pValue & 0x4) == 0 ? '-' : 'r';
            CH7 = (pValue & 0x2) == 0 ? '-' : 'w';
            if ((pValue & 0x200) == 0) CH8 = (pValue & 0x1) == 0 ? '-' : 'x';
            else CH8 = (pValue & 0x1) == 0 ? 'T' : 't';
            return string.Format("{0}{1}{2}{3}{4}{5}{6}{7}{8}", CH0, CH1, CH2, CH3, CH4, CH5, CH6, CH7, CH8);
        }
        /// <summary>Prevod retazca na mod</summary>
        /// <param name="pValue">retazec</param>
        /// <returns>hodnota</returns>
        public static uint StringToUnixMode(string pValue)
        {
            if (pValue.Length != 9) return 0; // Chybny vstup?
            uint Result = 0;
            if (pValue[0] == 'r') Result |= 0x100;
            if (pValue[1] == 'w') Result |= 0x80;
            if ((pValue[2] == 'x') || (pValue[2] == 's')) Result |= 0x40;
            if (pValue[3] == 'r') Result |= 0x20;
            if (pValue[4] == 'w') Result |= 0x10;
            if ((pValue[5] == 'x') || (pValue[5] == 's')) Result |= 0x08;
            if (pValue[6] == 'r') Result |= 0x04;
            if (pValue[7] == 'w') Result |= 0x02;
            if ((pValue[8] == 'x') || (pValue[8] == 't')) Result |= 0x01;
            if ((pValue[2] == 's') || (pValue[2] == 'S')) Result |= 0x800;
            if ((pValue[5] == 's') || (pValue[5] == 'S')) Result |= 0x400;
            if ((pValue[8] == 't') || (pValue[8] == 'T')) Result |= 0x200;

            return Result;
        }
        /// <summary>Test ci je zadany retazec HEX reprezentacia cisla</summary>
        /// <param name="pValue">retazec</param>
        /// <returns>true / false</returns>
        public static bool IsHexNumber(string pValue)
        {
            foreach (char C in pValue)
            {
                if ((C >= '0') && (C <= '9')) continue;
                if ((C >= 'a') && (C <= 'f')) continue;
                if ((C >= 'A') && (C <= 'F')) continue;
                return false;
            }
            return true; // Je to HEX
        }
        /// <summary>Prevod MSDOS casu na DateTime</summary>
        /// <param name="pValue">MSDOS cas</param>
        /// <returns>datetime objekt</returns>
        public static DateTime MSDOSTime2DateTime(uint pValue)
        {
            int day = 0;
            int month = 0;
            int year = 0;
            int second = 0;
            int hour = 0;
            int minute = 0;
            ushort hiWord;
            ushort loWord;
            hiWord = (ushort)((pValue & 0xFFFF0000) >> 16);
            loWord = (ushort)(pValue & 0xFFFF);
            year = ((hiWord & 0xFE00) >> 9) + 1980;
            month = (hiWord & 0x01E0) >> 5;
            day = hiWord & 0x1F;
            hour = (loWord & 0xF800) >> 11;
            minute = (loWord & 0x07E0) >> 5;
            second = (loWord & 0x1F) << 1;
            return new DateTime(year, month, day, hour, minute, second);
        }
        /// <summary>Prevod unix atributov na bitove pole</summary>
        /// <param name="pValue">hodnota</param>
        /// <param name="Result">bitove pole</param>
        public static void UnixModeToBoolArray(uint pValue, bool[] Result)
        {
            Result[0] = (pValue & 0x800) != 0;
            Result[1] = (pValue & 0x400) != 0;
            Result[2] = (pValue & 0x200) != 0;
            Result[3] = (pValue & 0x100) != 0;
            Result[4] = (pValue & 0x080) != 0;
            Result[5] = (pValue & 0x040) != 0;
            Result[6] = (pValue & 0x020) != 0;
            Result[7] = (pValue & 0x010) != 0;
            Result[8] = (pValue & 0x008) != 0;
            Result[9] = (pValue & 0x004) != 0;
            Result[10] = (pValue & 0x002) != 0;
            Result[11] = (pValue & 0x001) != 0;
        }
        /// <summary>Prevod unix atributov na bitove pole</summary>
        /// <param name="pValue">hodnota</param>
        /// <param name="Result">bitove pole</param>
        public static bool[] UnixModeToBoolArray(uint pValue)
        {
            bool[] Result = new bool[12]; // Alokujem pole
            UnixModeToBoolArray(pValue, Result); // Volam vyplnenie
            return Result;
        }
        /// <summary>Prevod bitoveho pola na unix atributy</summary>
        /// <param name="pValues">bitove pole</param>
        /// <returns>unix atributy</returns>
        public static uint BoolArrayToUnixMode(bool[] pValues)
        {
            uint R = 0;
            if (pValues[0]) R |= 0x800;
            if (pValues[1]) R |= 0x400;
            if (pValues[2]) R |= 0x200;
            if (pValues[3]) R |= 0x100;
            if (pValues[4]) R |= 0x080;
            if (pValues[5]) R |= 0x040;
            if (pValues[6]) R |= 0x020;
            if (pValues[7]) R |= 0x010;
            if (pValues[8]) R |= 0x008;
            if (pValues[9]) R |= 0x004;
            if (pValues[10]) R |= 0x002;
            if (pValues[11]) R |= 0x001;
            return R; // Vysledok
        }
        /// <summary>Prevod milisekund na casove zobrazenie</summary>
        /// <param name="pValue">hodnota</param>
        /// <returns>vysledok</returns>
        public static string Miliseconds2DispString(int pValue)
        {
            int Val = pValue;
            int H = pValue / (60 * 60 * 1000);
            Val -= (H * 60 * 60 * 1000);
            int M = Val / (60 * 1000);
            Val -= (M * 60 * 1000);
            int S = Val / (1000);
            int MSec = Val - (S * 1000);

            return string.Format("{0:D2}:{1:D2}:{2:D2}.{3:D3}", H, M, S, MSec);
        }

        /// <summary>Ziskanie poctu jednotkovych bitov</summary>
        /// <param name="pValue">hodnota</param>
        /// <returns>pocet jednotkovych bitov</returns>
        public static int GetCount1(uint pValue)
        {
            int C = 0; // Pocitadlo
            uint M = 0x1;
            for (int i = 0; i < 32; i++)
            {
                if ((M & pValue) != 0) C++;
                M <<= 1;
            }
            return C; // Vratim pocet
        }

        /// <summary>Ziskanie podretazca</summary>
        /// <param name="pValue">retazec</param>
        /// <param name="pIndex">cislo podretazca</param>
        /// <param name="pSeparator">oddelovac</param>
        /// <returns>podretazec alebo prazdny retazec</returns>
        public static string GetSubstring(string pValue, int pIndex, char pSeparator = '\b')
        {
            int I = 0;
            int C = 0;
            int FirstI = pValue.IndexOf(pSeparator); // Prvy oddelovac

            while (true)
            {
                int I1 = pValue.IndexOf(pSeparator, I);
                if (I1 == -1)
                {
                    if (C != pIndex) // Index mimo rozsah?
                    {
                        return FirstI == -1 ? pValue : pValue.Substring(0, FirstI); 
                    }
                    return pValue.Substring(I); // Ziadany je posledny podretazec
                }
                if (C == pIndex)
                {
                    return pValue.Substring(I, I1 - I); // Je to hladany podretazec
                }
                I = I1 + 1; // Dalsi podretazec
                C++;
            }
        }
        /// <summary>Zakodovanie retazca metodou Base64</summary>
        /// <param name="pValue">retazec na zakodovanie</param>
        /// <returns>zakodovany vysledok</returns>
        public static string Base64Encode(string pValue)
        {
            try
            {
                if (string.IsNullOrEmpty(pValue)) return ""; // Prazdny vstup?
                return Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(pValue)); // Volam kodovanie a vratim vysledok
            }
            catch
            {
                return ""; // Chyba
            }
        }
        /// <summary>Dekodovanie retazca metodou Base64</summary>
        /// <param name="pValue">zakodovany vstup</param>
        /// <returns>dekodovany vysledok</returns>
        public static string Base64Decode(string pValue)
        {
            try
            {
                if (string.IsNullOrEmpty(pValue)) return ""; // Prazdny vstup?
                return System.Text.Encoding.Default.GetString(Convert.FromBase64String(pValue)); // Volam dekodovanie a vratim vysledok
            }
            catch
            {
                return ""; // Chyba
            }
        }
        /// <summary>Zakodovanie retazca metodou Base64</summary>
        /// <param name="pValue">data na zakodovanie</param>
        /// <returns>zakodovany vysledok</returns>
        public static string Base64EncodeData(byte[] pValue)
        {
            try
            {
                if ((pValue == null) || (pValue.Length == 0)) return ""; // Prazdny vstup?
                return System.Convert.ToBase64String(pValue);
            }
            catch
            {
                return ""; // Chyba
            }
        }
        /// <summary>Dekodovanie retazca metodou Base64</summary>
        /// <param name="pValue">zakodovany vstup</param>
        /// <returns>dekodovany vysledok</returns>
        public static byte[] Base64DecodeData(string pValue)
        {
            try
            {
                if (string.IsNullOrEmpty(pValue)) return null; // Prazdny vstup?
                return Convert.FromBase64String(pValue); // 
            }
            catch
            {
                return null; // Chyba
            }
        }
        /// <summary>Ziskanie MD5 hash kodu retazca</summary>
        /// <param name="pData">retazec</param>
        /// <returns>kod alebo 0</returns>
        public static ulong GetMD5HashCode(string pData)
        {
            if (string.IsNullOrEmpty(pData)) return 0; // Prazdny vstup?
            try
            {
                System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
                md5.ComputeHash(System.Text.Encoding.Default.GetBytes(pData)); // Vypocitam hash
                
                ulong R = 0;
                byte[] Result = md5.Hash;
                for (int i = 0; i < 8; i++) // Prevediem na ulong
                {
                    R <<= 8; R |= (ulong)Result[i];
                }
                return R; // Mam vysledok
            }
            catch
            {
                return 0; // Chyba
            }
        }

        /// <summary>Prevod unmanaged dat na managed</summary>
        /// <param name="pLength">dlzka</param>
        /// <param name="pSourceData">zdroj</param>
        /// <param name="Destination">ciel</param>
        public static void Unmanaged2ManagedData(int pLength, IntPtr pSourceData, byte[] Destination)
        {
            for (int i = 0; i < pLength; i++) Destination[i] = System.Runtime.InteropServices.Marshal.ReadByte(pSourceData, i);
        }

        /// <summary>Vymazanie posledneho existujuceho znaku</summary>
        /// <param name="pValue">retazec pre spracovanie</param>
        /// <param name="pChar">znak pre odmazanie</param>
        /// <returns>vysledok</returns>
        public static string DeleteLastExistingChar(string pValue, char pChar)
        {
            int L = pValue.Length - 1; // Index na posledny znak
            return (L >= 0) && (pValue[L] == pChar) ? pValue.Substring(0, L) : pValue;
        }
        /// <summary>Pripojenie unikatneho znaku na koniec retazca</summary>
        /// <param name="pValue">retazec pre spracovanie</param>
        /// <param name="pChar">znak</param>
        /// <returns>vysledok</returns>
        public static string AppendUniqueChar(string pValue, char pChar)
        {
            int L = pValue.Length - 1;
            return ((L >= 0) && (pValue[L] != pChar)) ? pValue + pChar.ToString() : pValue;
        }
        /// <summary>Vytvorenie retazca ako pole rovnakych znakov</summary>
        /// <param name="pChar">znak</param>
        /// <param name="pLength">pocet</param>
        /// <returns>vysledok</returns>
        public static string CreateStringOfChars(char pChar, int pLength)
        {
            char[] B = new char[pLength];
            for (int i = 0; i < pLength; i++) B[i] = pChar;
            return new string(B);
        }
        /// <summary>Zarovnanie retazca na zadanu dlzku doplnenim znaku zlava</summary>
        /// <param name="pValue">hodnota</param>
        /// <param name="pChar">znak</param>
        /// <param name="pLength">vysledna dlzka</param>
        /// <returns>vysledok</returns>
        public static string AlignStringFromLeft(string pValue, char pChar, int pLength)
        {
            if (pValue.Length > pLength) return pValue.Substring(pValue.Length - pLength); // Vstup je vacsi?
            if (pValue.Length == pLength) return pValue; // Vstup je tak akurat?
            return CreateStringOfChars(pChar, pLength - pValue.Length) + pValue; // Doplnim znaky zlava
        }

        /// <summary>Prevod ulong na retazec</summary>
        /// <param name="pValue">hodnota</param>
        /// <param name="pMode">mod prevodu</param>
        /// <returns>prevedeny retazec</returns>
        public static string ULong2Str(ulong pValue, int pMode, string pThousandSeparator = ThousandSeparator)
        {
            switch (pMode)
            {
                default:
                    {
                        string S = pValue.ToString();
                        switch (S.Length)
                        {
                            case 4: return S.Substring(0, 1) + pThousandSeparator + S.Substring(1, 3);
                            case 5: return S.Substring(0, 2) + pThousandSeparator + S.Substring(2, 3);
                            case 6: return S.Substring(0, 3) + pThousandSeparator + S.Substring(3, 3);
                            case 7: return S.Substring(0, 1) + pThousandSeparator + S.Substring(1, 3) + pThousandSeparator + S.Substring(4, 3);
                            case 8: return S.Substring(0, 2) + pThousandSeparator + S.Substring(2, 3) + pThousandSeparator + S.Substring(5, 3);
                            case 9: return S.Substring(0, 3) + pThousandSeparator + S.Substring(3, 3) + pThousandSeparator + S.Substring(6, 3);
                            case 10: return S.Substring(0, 1) + pThousandSeparator + S.Substring(1, 3) + pThousandSeparator + S.Substring(4, 3) + pThousandSeparator + S.Substring(7, 3);
                            case 11: return S.Substring(0, 2) + pThousandSeparator + S.Substring(2, 3) + pThousandSeparator + S.Substring(5, 3) + pThousandSeparator + S.Substring(8, 3);
                            case 12: return S.Substring(0, 3) + pThousandSeparator + S.Substring(3, 3) + pThousandSeparator + S.Substring(6, 3) + pThousandSeparator + S.Substring(9, 3);
                            case 13: return S.Substring(0, 1) + pThousandSeparator + S.Substring(1, 3) + pThousandSeparator + S.Substring(4, 3) + pThousandSeparator + S.Substring(7, 3) + pThousandSeparator + S.Substring(10, 3);
                            case 14: return S.Substring(0, 2) + pThousandSeparator + S.Substring(2, 3) + pThousandSeparator + S.Substring(5, 3) + pThousandSeparator + S.Substring(8, 3) + pThousandSeparator + S.Substring(11, 3);
                            case 15: return S.Substring(0, 3) + pThousandSeparator + S.Substring(3, 3) + pThousandSeparator + S.Substring(6, 3) + pThousandSeparator + S.Substring(9, 3) + pThousandSeparator + S.Substring(12, 3);
                            default: return S;
                        }
                    }
            }
        }
        /// <summary>Prevod double na retazec</summary>
        /// <param name="pValue">hodnota</param>
        /// <param name="pMode">mod prevodu</param>
        /// <returns>prevedeny retazec</returns>
        public static string Double2Str(double pValue, int pDecimals, int pMode, string pThousandSeparator = ThousandSeparator)
        {
            switch (pMode)
            {
                default:
                    {
                        string S = Dbl2Str(pValue, pDecimals);
                        int I = S.IndexOf(',');
                        ulong U = (ulong)pValue;
                        return I == -1 ? ULong2Str(U, pMode, pThousandSeparator) : ULong2Str(U, pMode, pThousandSeparator) + S.Substring(I);
                    }
            }
        }
        /// <summary>Prevod velkosti na retazec</summary>
        /// <param name="pValue">hodnota</param>
        /// <param name="pMode">mod prevodu</param>
        /// <returns>prevedeny retazec</returns>
        public static string Size2String(ulong pValue, int pMode, string pThousandSeparator = ThousandSeparator)
        {
            switch (pMode)
            {
                case 1:
                    {
                        double D = (double)pValue;
                        if (D < (2.0 * 1024.0))
                        {
                            return ULong2Str(pValue, 0, pThousandSeparator) + " B";
                        }
                        D /= 1024.0;
                        if (D < (2.0 * 1024.0))
                        {
                            return Double2Str(D, 2, 0, pThousandSeparator) + " kB";
                        }
                        D /= 1024.0;
                        if (D < (2.0 * 1024.0))
                        {
                            return Double2Str(D, 2, 0, pThousandSeparator) + " MB";
                        }
                        D /= 1024.0;
                        return Double2Str(D, 2, 0, pThousandSeparator) + " GB";
                    }
                default: return ULong2Str(pValue, pMode, pThousandSeparator) + " B";
            }
        }
        /// <summary>Ohranicenie retazca</summary>
        /// <param name="pLeft">lave ohranicenie</param>
        /// <param name="pValue">retazec</param>
        /// <param name="pRight">prave ohranicenie</param>
        /// <param name="pApply">priznak aplikovania</param>
        /// <returns>vysledok</returns>
        public static string BoundString(string pLeft, string pValue, string pRight, bool pApply)
        {
            return pApply ? pLeft + pValue + pRight : pValue;
        }
        /// <summary>Transformacia zoznamu retazcov na string</summary>
        /// <param name="pList">zoznam</param>
        /// <param name="pSeparator">oddelovac retazcov</param>
        /// <returns>vysledok</returns>
        public static string StringList2String(System.Collections.Generic.List<string> pList, string pSeparator = "\n")
        {
            System.Text.StringBuilder B = new System.Text.StringBuilder(); // Builder

            int C = pList.Count - 1; // Ziskam pocet zaznamov
            for (int i = 0; i <= C; i++)
            {
                B.Append(pList[i]);
                if (i != C) B.Append(pSeparator);
            }

            return B.ToString(); // Vratim vysledok
        }
        /// <summary>Prevod retazca na zoznam retazcov</summary>
        /// <param name="pText">text</param>
        /// <returns>zoznam retazcov</returns>
        public static System.Collections.Generic.List<string> String2StringList(string pText, string pSeparator = "\n")
        {
            System.Collections.Generic.List<string> List = new System.Collections.Generic.List<string>(); // Vytvorim objekt

            int SepLen = pSeparator.Length;
            int I = 0;
            string Line;

            while (true)
            {
                int I1 = pText.IndexOf(pSeparator, I); // Hladam oddelovac
                if (I1 == -1) Line = pText.Substring(I);
                else
                {
                    if (I1 == I) Line = "";
                    else Line = pText.Substring(I, I1 - I);
                }
                if (Line != "") List.Add(Line); // Zaradim neprazdny riadok

                if (I1 == -1) break; // Koniec?
                I = I1 + SepLen; // Dalsi riadok
                if (I == pText.Length) break; // Koniec?
            }

            return List; // Vratim vysledok
        }
        /// <summary>Transformacia zoznamu retazcov na dictionary tabulku</summary>
        /// <param name="pList">zoznam retazcov</param>
        /// <returns>dictionary tabulka</returns>
        public static System.Collections.Generic.Dictionary<string, int> StringList2DictionaryTable(System.Collections.Generic.List<string> pList)
        {
            System.Collections.Generic.Dictionary<string, int> Result = new System.Collections.Generic.Dictionary<string, int>(); // Vytvorim objekt
            foreach (string S in pList)
            {
                if (Result.ContainsKey(S)) continue; // Uz je v tabulke?
                Result.Add(S, 0); // Zaradim
            }
            return Result;
        }
        /// <summary>Prevod int cisla na retazec s uvodnymi nulami</summary>
        /// <param name="pValue">hodnota</param>
        /// <param name="pMaxValue">max. hodnota</param>
        /// <param name="pMinDigits">minimalny pocet cislic</param>
        /// <returns>prevedena hodnota</returns>
        public static string FormatDECNumber(int pValue, int pMaxValue, int pMinDigits = -1)
        {
            int I = pMaxValue;
            int NumC = 1;
            while (I > 9) // Ziskam pocet potrebnych cislic
            {
                I /= 10;
                NumC++;
            }

            if ((pMinDigits != -1) && (NumC < pMinDigits)) NumC = pMinDigits; // Upravim

            return pValue.ToString(string.Format("D{0}", NumC)); // Prevediem
        }
        /// <summary>Transformacia zoznamu retazcov na pole string</summary>
        /// <param name="pList">zoznam</param>
        /// <param name="pSeparator">oddelovac retazcov</param>
        /// <returns>vysledok</returns>
        public static string[] StringList2StringArray(System.Collections.Generic.List<string> pList)
        {
            string[] Result = new string[pList.Count];
            int C = pList.Count; // Pocet zaznamov
            for (int i = 0; i < C; i++) Result[i] = pList[i]; // Skopirujem hodnoty
            return Result; // Vratim pole
        }
        /// <summary>Zmena prveho znaku na velke pismeno</summary>
        /// <param name="pValue">vstup</param>
        /// <returns>vysledok</returns>
        public static string FirstUpperChar(string pValue)
        {
            if (string.IsNullOrEmpty(pValue)) return "";
            return char.ToUpper(pValue[0]) + pValue.Substring(1);
        }
        /// <summary>Zmena prvych znakov slov na velke pismeno</summary>
        /// <param name="pValue">vstup</param>
        /// <returns>vysledok</returns>
        public static string FirstWordUpperChar(string pValue)
        {
            if (string.IsNullOrEmpty(pValue)) return "";
            System.Text.StringBuilder B = new System.Text.StringBuilder();
            char LastC = (char)0; // Posledny znak
            foreach (char C in pValue) // Prechadzam znaky
            {
                char C1 = C;
                if (C > ' ') // Nie je to medzera?
                {
                    if (LastC <= ' ') C1 = char.ToUpper(C); // Je posledny znak medzera?
                }
                B.Append(C1);
                LastC = C;
            }
            return B.ToString(); // Vratim vysledok
        }
        /// <summary>Vykonanie nahrady podretazcov</summary>
        /// <param name="pValue">retazec pre spracovanie</param>
        /// <param name="pFrom">podretazec pre nahradenie</param>
        /// <param name="pTo">nahrada</param>
        /// <param name="pIgnoreCase">priznak ignorovania case</param>
        /// <returns>vysledok</returns>
        public static string ReplaceStr(string pValue, string pFrom, string pTo, bool pIgnoreCase)
        {
            if (!pIgnoreCase) return pValue.Replace(pFrom, pTo);
            System.Text.StringBuilder B = new System.Text.StringBuilder();

            int I = 0;
            while (I < pValue.Length)
            {
                int I1 = pValue.IndexOf(pFrom, I, StringComparison.InvariantCultureIgnoreCase);
                if (I1 == -1)
                {
                    B.Append(pValue.Substring(I));
                    break;
                }
                int L = I1 - I;
                if (L > 0) B.Append(pValue.Substring(I, L));
                if (pTo.Length > 0) B.Append(pTo);
                I = I1 + pTo.Length + 1;
            }
            return B.ToString();
        }

        /// <summary>Skopirovanie obsahu zoznamu ikoniek</summary>
        /// <param name="pSource">zdroj</param>
        /// <param name="pDestination">ciel</param>
        public static void CopyImageList(System.Windows.Forms.ImageList pSource, System.Windows.Forms.ImageList pDestination)
        {
            pDestination.Images.Clear(); // Zrusim obsah
            int C = pSource.Images.Count;
            for (int i = 0; i < C; i++)
            {
                AddImageToImageList(pDestination, pSource.Images[i]);
            }
        }
        /// <summary>Zaradenie ikony do zoznamu</summary>
        /// <param name="pList">zoznam</param>
        /// <param name="pIcon">ikona</param>
        /// <returns>pozicia</returns>
        public static int AddIconToImageList(System.Windows.Forms.ImageList pList, System.Drawing.Icon pIcon)
        {
            string Hash = ((uint)pIcon.GetHashCode()).ToString(); // Ziskam hash
            try
            {
                if (pList.Images.ContainsKey(Hash)) return pList.Images.IndexOfKey(Hash);
            }
            catch
            {
            }
            pList.Images.Add(Hash, pIcon); // Zaradim ikonu a vratim poziciu
            return pList.Images.Count - 1;
        }
        /// <summary>Zaradenie ikony do zoznamu</summary>
        /// <param name="pList">zoznam</param>
        /// <param name="pIcon">ikona</param>
        /// <returns>pozicia</returns>
        public static int AddImageToImageList(System.Windows.Forms.ImageList pList, System.Drawing.Image pIcon)
        {
            try
            {
                string Hash = ((uint)pIcon.GetHashCode()).ToString(); // Ziskam hash
                if (pList.Images.ContainsKey(Hash)) return pList.Images.IndexOfKey(Hash);
                pList.Images.Add(Hash, pIcon); // Zaradim ikonu a vratim poziciu
                return pList.Images.Count - 1;
            }
            catch
            {
                return -1;
            }
        }
        /// <summary>Ziskanie textoveho popisu fontu</summary>
        /// <param name="pValue">objekt pre popis</param>
        public static string GetFontDisplayName(System.Drawing.Font pValue)
        {
            string S = pValue.Name + "  " + Math.Round(pValue.Size, 1).ToString().Replace(',', '.') + " pt  ";
            if (pValue.Bold) S += "bold  ";
            if (pValue.Italic) S += "italic  ";
            return S.Trim().Replace("  ", ", ");
        }

        /// <summary>Skopirovanie textu do schranky</summary>
        /// <param name="pText">text</param>
        public static bool CopyTextToClipboard(string pText)
        {
            try
            {
                System.Windows.Forms.Clipboard.Clear();
                System.Windows.Forms.Clipboard.SetText(pText, System.Windows.Forms.TextDataFormat.Text);
                return true;
            }
            catch
            {
                return false;
            }
        }
        /// <summary>Skopirovanie zoznamu retazcov do schranky</summary>
        /// <param name="pList">zoznam</param>
        public static bool CopyStringListToClipboard(System.Collections.Generic.List<string> pList)
        {
            try
            {
                // Vykonam ulozenie do schranky
                System.Windows.Forms.Clipboard.Clear();
                System.Windows.Forms.Clipboard.SetText(ICore.StringList2String(pList, System.Environment.NewLine), System.Windows.Forms.TextDataFormat.Text);
                return true;
            }
            catch
            {
                return false;
            }
        }
        /// <summary>Ziskanie textu zo schranky</summary>
        /// <returns>text alebo null</returns>
        public static string PasteTextFromClipboard()
        {
            string Result = null;

            try
            {
                // Vykonam ulozenie do schranky
                if (System.Windows.Forms.Clipboard.ContainsText())
                {
                    Result = System.Windows.Forms.Clipboard.GetText(System.Windows.Forms.TextDataFormat.Text);
                }
                return Result; // Vratim vysledok
            }
            catch
            {
                return null;
            }
        }
        /// <summary>Ziskanie textu zo schranky</summary>
        /// <returns>text alebo null</returns>
        public static System.Collections.Generic.List<string> PasteStringListFromClipboard()
        {
            string Text = null;

            try
            {
                // Vykonam ulozenie do schranky
                if (System.Windows.Forms.Clipboard.ContainsText())
                {
                    Text = System.Windows.Forms.Clipboard.GetText(System.Windows.Forms.TextDataFormat.Text);
                }
                if (Text == null) return null;
                return ICore.String2StringList(Text, System.Environment.NewLine); // Prevediem na zoznam
            }
            catch
            {
                return null;
            }
        }
        /// <summary>Ziskanie typu dat v schranke</summary>
        /// <returns>typ dat alebo 0 pre neznamy typ alebo prazdnu schranku</returns>
        public static int GetClipboardDataType()
        {
            try
            {
                if (System.Windows.Forms.Clipboard.ContainsText()) return CLIPBOARD_TYPE_TEXT;
                if (System.Windows.Forms.Clipboard.ContainsImage()) return CLIPBOARD_TYPE_BITMAP;
                return 0;
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>Ziskanie objektu ImageCodecInfo pre zadany typ suboru</summary>
        /// <param name="pMimeType">typ</param>
        /// <returns>objekt alebo null</returns>
        public static System.Drawing.Imaging.ImageCodecInfo GetEncoderInfo(string pMimeType)
        {
            System.Drawing.Imaging.ImageCodecInfo[] encoders = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
            for (int i = 0; i < encoders.Length; i++)
            {
                if (string.Compare(encoders[i].MimeType, pMimeType, true) == 0) return encoders[i];
            }
            return null;
        }

        /// <summary>Ziskanie ID procesora</summary>
        /// <returns>ID alebo 0</returns>
        public static ulong GetProcessorID()
        {
            try
            {
                System.Management.ManagementObjectCollection mbsList = null;
                System.Management.ManagementObjectSearcher mbs = new System.Management.ManagementObjectSearcher("Select * From Win32_processor");
                mbsList = mbs.Get();

                string id = "";
                foreach (System.Management.ManagementObject mo in mbsList)
                {
                    id = mo["ProcessorID"].ToString();
                    if (id != "") break;
                }
                return ICore.GetMD5HashCode(id);
            }
            catch
            {
                return 0; // Nejaka chyba
            }
        }
        /// <summary>Ziskanie ID zakladnej dosky</summary>
        /// <returns>ID alebo 0</returns>
        public static ulong GetMBID()
        {
            try
            {
                System.Management.ManagementObjectSearcher mos = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_BaseBoard");
                System.Management.ManagementObjectCollection moc = mos.Get();
                string serial = "";
                foreach (System.Management.ManagementObject mo in moc)
                {
                    serial = (string)mo["SerialNumber"];
                    if (serial != "") break;
                } 
                return ICore.GetMD5HashCode(serial);
            }
            catch
            {
                return 0; // Nejaka chyba
            }
        }

        /// <summary>Ziskanie obsahu URL stranky</summary>
        /// <param name="pURL">url adresa</param>
        /// <returns></returns>
        public static string GetWebPage(string pURL)
        {
            try
            {
                using (System.Net.WebClient WC = new System.Net.WebClient())
                {
                    return WC.DownloadString(pURL);
                }
            }
            catch
            {
                return null;
            }
        }
    }

    /// <summary>Trieda IThrSafeVariable</summary>
    public class IThrSafeVariable
    {
        protected object FLockObject;
        protected bool FBoolValue;
        protected int FIntValue;
        protected string FStringValue;

        /// <summary>Konstruktor</summary>
        public IThrSafeVariable()
        {
            FLockObject = new object();
            FBoolValue = false;
        }

        /// <summary>Property: BoolValue</summary>
        public bool BoolValue
        {
            get
            {
                //System.Threading.Monitor.Enter(FLockObject);
                //bool B = FBoolValue;
                //System.Threading.Monitor.Exit(FLockObject);
                //return B;
                return FBoolValue;
            }
            set
            {
                System.Threading.Monitor.Enter(FLockObject);
                FBoolValue = value;
                System.Threading.Monitor.Exit(FLockObject);
            }
        }
        /// <summary>Property: IntValue</summary>
        public int IntValue
        {
            get
            {
                System.Threading.Monitor.Enter(FLockObject);
                int V = FIntValue;
                System.Threading.Monitor.Exit(FLockObject);
                return V;
            }
            set
            {
                System.Threading.Monitor.Enter(FLockObject);
                FIntValue = value;
                System.Threading.Monitor.Exit(FLockObject);
            }
        }
        /// <summary>Property: StringValue</summary>
        public string StringValue
        {
            get
            {
                System.Threading.Monitor.Enter(FLockObject);
                string V = FStringValue;
                System.Threading.Monitor.Exit(FLockObject);
                return V;
            }
            set
            {
                System.Threading.Monitor.Enter(FLockObject);
                FStringValue = value;
                System.Threading.Monitor.Exit(FLockObject);
            }
        }
    }

}
